/**
 * \file UARTSendData.h
 * 
 * \brief 串口数据发送抽象接口
 *
 * \author 高明飞
 *
 * \date 2015-07-19
 *
 * \details 
 * 本程序主要封装了一些常用的串口数据发送函数，便于不同项目中重复使用。
 * 需要配合底层HAL程序使用。
 * 
 * \note
 * 程序中未包含具体的底层实现方法，在使用时需要根据具体平台改写相关宏定义。
 *
 * 修改记录：\n
 *
 * 2015-09-12 :\n
 *   -Bug Fixed;\n
 *   -添加UART_LEGACY宏定义\n
 *
 * 2015-09-26 :\n
 *   -修改注释格式使其可以使用Doxygen\n
 * 
 */
 
#ifndef UARTSENDDATA_H
#define UARTSENDDATA_H
 
/* C++ */
#ifdef __cplusplus  
extern "C" {
#endif 

/*--------------------此部分需要修改--------------------*/
/* 编译选项开关，部分编译器（如51）不支持inline、va_list等，此时不使用内联函数，不实现printf() */
#define UART_LEGACY

/* 如未定义uint8_t等基本数据类型，需要先定义 */
#include "TypeDef.h"

/* HAL层提供的UART底层实现宏定义，此处以TMS320F28027为例，需要根据实际情况修改 */

/* HAL头文件 */
#include "STC15F2K60S2.h"
	
/**
 * UART发送数据宏定义，一般发送数据都是向某个寄存器中写入一个8位数据。
 * 此处data即为要发送的8位（1 byte）数据。
 */
#define HAL_UART_SEND_UINT8(UARTdata) (TI = 0,SBUF = UARTdata)

/**
 * UART判断是否可以发送新数据宏定义。
 * 一般都存在一个寄存器可以用于判断此时TX Buffer是否可以接收新数据。
 * 可以发送数据时，宏的值应为非0值；
 * 当宏的值为0时，代表此时不能发送新数据。
 */
#define HAL_UART_TX_READY (TI)
 
/*--------------------此部分需要修改--------------------*/


#ifdef UART_LEGACY
void UARTSendChar(const char c);
#else
/**
 * 发送一个字符
 * 
 * \param c: 需要发送的字符
 *
 */
inline void UARTSendChar(const char c)
{
  while(!HAL_UART_TX_READY);
  HAL_UART_SEND_UINT8(c);
}
#endif



#ifdef UART_LEGACY
void UARTSendByte(const uint8_t UARTdata);
#else
/**
 * 发送一个二进制数据，以字节形式
 *
 * \param UARTdata: 需要发送的数据
 *
 */
inline void UARTSendByte(const uint8_t UARTdata)
{
  while(!HAL_UART_TX_READY);
  HAL_UART_SEND_UINT8(UARTdata);
}
#endif



#ifdef UART_LEGACY
void UARTSendWord(const uint16_t UARTdata);
#else
/**
 * 发送一个二进制数据，以字(WORD, 2 Bytes)形式
 *
 * \param UARTdata: 需要发送的数据
 *
 * \note MSB First
 *
 */
inline void UARTSendWord(const uint16_t UARTdata)
{
  while(!HAL_UART_TX_READY);
  HAL_UART_SEND_UINT8((uint8_t)(UARTdata>>8 & 0x00FF));
  while(!HAL_UART_TX_READY);
  HAL_UART_SEND_UINT8((uint8_t)(UARTdata & 0x00FF));
}
#endif



#ifdef UART_LEGACY
void UARTSendDword(const uint32_t UARTdata);
#else
/**
 * 发送一个二进制数据，以双字(DWORD, 4 Bytes)形式
 *
 * \param UARTdata: 需要发送的数据
 *
 * \note MSB First
 *
 */
inline void UARTSendDword(const uint32_t UARTdata)
{
  while(!HAL_UART_TX_READY);
  HAL_UART_SEND_UINT8((uint8_t)(UARTdata>>24 & 0x00FF));
  while(!HAL_UART_TX_READY);
  HAL_UART_SEND_UINT8((uint8_t)(UARTdata>>16 & 0x00FF));
  while(!HAL_UART_TX_READY);
  HAL_UART_SEND_UINT8((uint8_t)(UARTdata>>8 & 0x00FF));
  while(!HAL_UART_TX_READY);
  HAL_UART_SEND_UINT8((uint8_t)(UARTdata & 0x00FF));
}
#endif


/**
 * 发送一个无符号二进制数据，以ASCII码形式
 *
 * \param UARTdata: 需要发送的数据
 *
 * \param base: 数据进制， 理论上支持2~36进制，常用值：
 * \arg 2: 二进制
 * \arg 10: 十进制
 * \arg 16: 十六进制
 *
 * \param align: 是否需要对齐
 * \arg 0: 无需对齐
 * \arg other: 指定的位数，若数据所需位数小于此值，将用0在前面补足
 *
 * \note 若数据所需位数大于align值，将按实际位数输出，不会截短。
 *
 */
void UARTSendUnsignASCII(uint32_t UARTdata, uint8_t base, uint8_t align);


/**
 * 发送一个带符号二进制数据，以ASCII码形式
 *
 * \param UARTdata: 需要发送的数据
 *
 * \param align: 是否需要对齐
 * \arg 0: 无需对齐
 * \arg other: 指定的位数，若数据所需位数小于此值，将用0在前面补足
 *
 * \note 若数据所需位数大于align值，将按实际位数输出，不会截短。
 * 		   此处的位数是指数据的位数，不包括前面的符号位。
 *
 */
void UARTSendSignASCII(int32_t UARTdata, uint8_t align);


/**
 * 发送字符串
 *
 * \param str: 字符串头指针
 *
 * \note 字符串需以'\0'结尾
 *
 */
void UARTSendString(const char * str);


/**
 * 发送二进制数据数组，以字节形式
 *
 * \param UARTdata: 数组头指针
 * \param num: 数组中数据个数
 *
 */
void UARTSendByteArray(const uint8_t * UARTdata, const uint16_t num);


/**
 * 发送二进制数据数组，以字(WORD, 2 Bytes)形式
 *
 * \param UARTdata: 数组头指针
 * \param num: 数组中数据个数
 *
 * \note MSB First
 *
 */
void UARTSendWordArray(const uint16_t * UARTdata, const uint16_t num);


/**
 * 发送二进制数据数组，以双字(DWORD, 4 Bytes)形式
 *
 * \param UARTdata: 数组头指针
 * \param num: 数组中数据个数
 *
 * \note MSB First
 *
 */
void UARTSendDwordArray(const uint32_t * UARTdata, const uint16_t num);


/**
 * 简易版printf函数
 *
 * \note
 * \param format: 格式化字符串，支持的占位符：
 * \arg %d: 带符号整数
 * \arg %u: 无符号整数, 十进制形式
 * \arg %x: 无符号整数, 十六进制形式, 自动补足至2、4、8位
 * \arg %b: 无符号整数, 二进制形式, 自动补足至8、16、32位
 * \arg %c: 一个ASCII字符
 * \arg %s: 字符串
 *
 * \warning 输入的数字类型必须为uint32_t，否则会发生错误
 */
#ifndef UART_LEGACY
void UARTprintf(const char *format, ...);
#endif


/* C++ */
#ifdef __cplusplus  
}
#endif
 
#endif
 
